const { Service } = require('egg'); require;
const { v4: uuidV4 } = require('uuid');
const moment = require('moment');
const order_table = 'order_info',
  order_process_table = 'order_process',
  user_table = 'user';
const formatStr = 'YYYY-MM-DD HH:mm:ss';

class ProcessService extends Service {
  async insert(order_id, status, type, title) {
    const ctx = this.ctx;
    try {
      const { id: user_id } = ctx.session;
      const time = moment();
      const instance = {
        uuid: uuidV4(),
        order_id, status, type, title,
        create_time: moment(time).format(formatStr),
        update_time: moment(time).format(formatStr),
        create_by: user_id,
        update_by: user_id,
        is_delete: 0,
      };

      return instance;
    } catch (error) {
      throw error;
    }
  }


  async stage(uuid, order, method, pageIndex, pageSize) {
    const ctx = this.ctx;
    try {
      const list = await ctx.app.knex().select('t1.name', 't2.type', 't2.status', 't2.title', 't1.update_by', 't1.create_by',
        't2.remark', 't1.level', 't1.create_time', 't1.update_time', 't3.name as create_name', 't4.name as update_name'
      )
        .from(`${order_table} as t1`)
        .leftJoin(`${order_process_table} as t2`, function() {
          this.on('t1.uuid', '=', 't2.order_id');
        })
        .leftJoin(`${user_table} as t3`, function() {
          this.on('t3.uuid', '=', 't2.create_by');
        })
        .leftJoin(`${user_table} as t4`, function() {
          this.on('t4.uuid', '=', 't2.update_by');
        })
        .whereRaw(` t1.uuid =  '${uuid}'`)
        .orderBy(order, method)
        .limit(Number(pageSize))
        .offset((Number(pageIndex) - 1) * Number(pageSize));

      const count = await ctx.app.knex().select('t1.uuid as count')
        .from(`${order_table} as t1`)
        .where('t1.uuid', uuid)
        .orderBy(order, method);

      const result = {
        list,
        count: count[0].count,
      };

      return result;
    } catch (error) {
      throw error;
    }
  }

  async update(order_id, status, remark) {
    const ctx = this.ctx;
    const trx = await ctx.app.knex.transaction();
    try {
      const { id: user_id } = ctx.session;
      const time = moment();
      const [ origin_instance ] = await ctx.app.knex(order_process_table)
        .select('*')
        .where({ order_id })
        .from(order_process_table)
        .limit(1)
        .orderBy('create_time', 'desc');


      let next_process_instance;
      // 判断当前是否是已经完成 如果已经完成这里相当于修改状态就行了，如果未完成则进入下一流程
      if (origin_instance.type === 4 || origin_instance === 5) {
        throw new Error('当前订单已被完成或者已被取消');
      } else {
        origin_instance.status = status;
        origin_instance.remark = remark;

        next_process_instance = await this.insertNextProcess(order_id, origin_instance.type + 1, user_id, time);
        /**
         * 进入阶段发送审批对应消息
         */
      }

      origin_instance.update_time = moment(time).format('YYYY-MM-DD HH:mm:ss');
      origin_instance.update_by = user_id;
      await trx(order_process_table).update(origin_instance);

      if (next_process_instance) {
        await trx(order_process_table).insert(next_process_instance);
      }

      await trx.commit();

      return origin_instance;
    } catch (error) {
      await trx.rollback();
      throw error;
    }
  }

  async trxFinish(order_id, remark, trx) {
    const ctx = this.ctx;
    try {
      const { id: user_id } = ctx.session;
      const time = moment();
      if (!trx) {
        throw new Error('数据库事务错误');
      }

      const origin_instance = await ctx.app.knex(order_process_table)
        .select('*')
        .where({ order_id })
        .orderBy('create_time', 'desc')
        .first();

      const next_process = await this.insertNextProcess(order_id, 4, user_id, time);

      origin_instance.remark = remark;
      origin_instance.status = 0;
      origin_instance.update_by = user_id;
      origin_instance.update_time = moment(time).format('YYYY-MM-DD HH:mm:ss');
      await trx(order_process_table).update(origin_instance).where({ uuid: origin_instance.uuid });
      await trx(order_process_table).insert(next_process);

      return;
    } catch (error) {
      throw error;
    }
  }

  async trxRefuse(order_id, remark, trx) {
    const ctx = this.ctx;
    try {
      const { id: user_id } = ctx.session;
      const time = moment();
      if (!trx) {
        throw new Error('数据库事务错误');
      }

      const origin_instance = await ctx.app.knex(order_process_table)
        .select('*')
        .where({ order_id })
        .orderBy('create_time', 'desc')
        .first();

      const next_process = await this.insertNextProcess(order_id, 1, user_id, time);

      origin_instance.remark = remark;
      origin_instance.status = 2;
      origin_instance.update_by = user_id;
      origin_instance.update_time = moment(time).format('YYYY-MM-DD HH:mm:ss');
      await trx(order_process_table).update(origin_instance).where({ uuid: origin_instance.uuid });
      await trx(order_process_table).insert(next_process);
      return next_process;
    } catch (error) {
      throw error;
    }
  }

  async trxCancel(order_id, remark, trx) {
    const ctx = this.ctx;
    try {
      const { id: user_id } = ctx.session;
      const time = moment();

      const origin_instance = await ctx.app.knex(order_process_table)
        .select('*')
        .where({ order_id })
        .orderBy('create_time', 'desc')
        .first();

      const next_process = await this.insertNextProcess(order_id, 6, user_id, time);

      origin_instance.remark = remark;
      origin_instance.status = 2;
      origin_instance.update_by = user_id;
      origin_instance.update_time = moment(time).format('YYYY-MM-DD HH:mm:ss');
      await trx(order_process_table).update(origin_instance).where({ uuid: origin_instance.uuid });
      await trx(order_process_table).insert(next_process);

      return next_process;
    } catch (error) {
      throw error;
    }
  }


  async trxChange(order_id, remark) {
    const ctx = this.ctx;
    const trx = await ctx.app.knex.transaction();
    try {
      const { user_id } = ctx.session;
      const time = moment();
      if (!trx) {
        throw new Error('数据库事务错误');
      }

      const origin_instance = await ctx.app.knex(order_process_table)
        .select('*')
        .where({ order_id })
        .orderBy('create_time', 'desc')
        .limit(1);

      const next_process = await this.insertNextProcess(order_id, 6, user_id, time);

      origin_instance.remark = remark;
      origin_instance.status = 2;
      origin_instance.update_by = user_id;
      origin_instance.update_time = moment(time).format('YYYY-MM-DD HH:mm:ss');
      await trx(order_process_table).update(origin_instance).where({ uuid: origin_instance.uuid });
      await trx(order_process_table).insert(next_process);

      await trx.commit();
      return;
    } catch (error) {
      await trx.rollback();
      throw error;
    }
  }

  async insertNextProcess(order_id, type, user_id, time) {
    const ctx = this.ctx;
    try {
      const list = ctx.processMap();
      const instance = {
        uuid: uuidV4(),
        order_id,
        status: 0,
        type,
        title: list[type - 1],
        create_by: user_id,
        update_by: user_id,
        create_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        is_delete: 0,
      };

      return instance;
    } catch (error) {
      throw error;
    }
  }
}

module.exports = ProcessService;
